import path from "path";
import fs from "node:fs";

// 一级缓存
const singletonObjects: Map<string, Object> = new Map();
// 二级缓存
const earlySingletonObjects: Map<string, Object> = new Map();
// 三级缓存
const singletonFactories: Map<string, ProxyConstructor> = new Map();

// 类与属性关系缓存
const objectPropertyMap: Map<string, string> = new Map();

// 缓存所有装饰器promise
let decoratorPromises: Promise<void>[] = [];

// bean定义集合
let beanDefinitionMap: Map<string, BeanDefinition> = new Map();
//
let beanPostProcessorList: BeanPostProcessor[] = [];

class BeanDefinition {
    scope: string;
    beanType: Function;

    constructor(scope: string, beanType: Function) {
        this.beanType = beanType;
        this.scope = "singleton";
    }
}

class BeanPostProcessor {
    postProcessBeforeInitialization(bean: Object, beanName: string): Object{
        return bean;
    }
    postProcessAfterInitialization(bean: Object, beanName: string): Object{
        return bean;
    }
}


// 使用类装饰器实现@Component注解
const Component = (name?: string): ClassDecorator => {
    return (target: Function) => {
        const instance = new target.prototype.constructor();
        // singletonObjects.set(name??target.name, instance);
        if (instance instanceof BeanPostProcessor) {
            beanPostProcessorList.push(instance);
        } else {
            beanDefinitionMap.set(name ?? target.name, new BeanDefinition('singleton', target));
        }
        decoratorPromises.push(Promise.resolve());
    };
};

// 使用属性装饰器实现@Autowired注解
const Autowired = (name?: string): PropertyDecorator => {
    return (target: Object, propertyKey: string | symbol) => {
        // 收集早期bean
        earlySingletonObjects.set(target.constructor.name, target);
        // 收集类属性关系
        objectPropertyMap.set(target.constructor.name, name ?? propertyKey.toString());
        decoratorPromises.push(Promise.resolve());
    };
};

async function init() {
    await Promise.all(decoratorPromises);
    beanDefinitionMap.forEach((value, name) => {
        if (value.scope === "singleton") {
            beanPostProcessorList.forEach((beanPostProcessor) => {
                beanPostProcessor.postProcessBeforeInitialization(
                    new value.beanType.prototype.constructor(),
                    name ?? value.beanType.name
                );
            });
            const instance = new value.beanType.prototype.constructor();
            beanPostProcessorList.forEach((beanPostProcessor) => {
                beanPostProcessor.postProcessAfterInitialization(
                    instance,
                    name ?? value.beanType.name
                );
            });
            singletonObjects.set(name ?? value.beanType.name, instance);
        }
    });
    earlySingletonObjects.forEach((value, key) => {
        // 获取需要注入的属性
        const propertyKey = objectPropertyMap.get(key);
        if (!propertyKey) {
            return;
        }
        // 获取注入属性的类型
        const propertyType = Reflect.getOwnMetadata(
            "design:type",
            value,
            propertyKey ?? ""
        );
        // 获取目标类的对象
        const targetPropertyInstance = singletonObjects.get(propertyType.name);
        if (targetPropertyInstance) {
            (value as any)[propertyKey] = targetPropertyInstance;
        }
        singletonObjects.set(key, value);
        console.log(singletonObjects);
    });
}

// init();

export {Component, Autowired, BeanPostProcessor, init, singletonObjects};
